package com.example.app2024.svg;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.core.graphics.PathParser;

import com.example.app2024.R;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

public class Mymap extends View
{
      private int[] colorArray = new int[]{0xff239bd7, 0xff30a9e5, 0xff80cbf1, 0xff4087a3};
      private List<ProvinceItem> itemList;
      private Paint paint;
      private ProvinceItem select;
      private RectF totalRect;
      private float scale = 1f;

      private static final int NONE = 0;
      private static final int DRAG = 1;
      private static final int ZOOM = 0;
      private int mode = NONE;

      //第一个按下的手指的点
      private PointF startPoint = new PointF();
      private PointF midPoint = new PointF();

      private float oriDis = 1f;
      private boolean actionClick = true;
      private float translateX;
      private float translateY;

      private boolean shouldShowText;

      public Mymap(Context context)
      {
            super(context);
            init();
      }

      private void init()
      {
            paint = new Paint();
            paint.setAntiAlias(true);
            itemList = new ArrayList<>();
            loadThread.start();
      }

      public Mymap(Context context, AttributeSet attrs)
      {
            super(context, attrs);
            init();
      }

      public Mymap(Context context, AttributeSet attrs, int defStyleAttr)
      {
            super(context, attrs, defStyleAttr);
            init();
      }

      private Thread loadThread = new Thread()
      {
            @Override
            public void run()
            {
                  InputStream inputStream = getResources().openRawResource(R.raw.chinahigh);
                  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                  DocumentBuilder builder;
                  try
                  {
                        builder = factory.newDocumentBuilder();
                        Document document = builder.parse(inputStream);
                        Element rootElement = document.getDocumentElement();
                        NodeList path = rootElement.getElementsByTagName("path");
                        float left = -1;
                        float right = -1;
                        float top = -1;
                        float bottom = -1;

                        List<ProvinceItem> list = new ArrayList<>();
                        for (int i = 0; i < path.getLength(); i++)
                        {
                              Element element = (Element) path.item(i);
                              String pathData = element.getAttribute("d");
                              String name = element.getAttribute("title");
                              //将pathdata转为path
                              Path path1 = PathParser.createPathFromPathData(pathData);
                              ProvinceItem provinceItem = new ProvinceItem(path1);
                              provinceItem.setName(name);
                              provinceItem.setDrawColor(colorArray[i % 4]);
                              RectF rectF = new RectF();
                              path1.computeBounds(rectF, true);

                              left = left == -1 ? rectF.left : Math.min(left, rectF.left);

                              right = right == -1 ? rectF.right : Math.max(right, rectF.right);
                              top = top == -1 ? rectF.top : Math.min(top, rectF.top);
                              bottom = bottom == -1 ? rectF.bottom : Math.max(bottom, rectF.bottom);
                              list.add(provinceItem);
                        }
                        itemList = list;
                        totalRect = new RectF(left, top, right, bottom); // 图片大小


                        Handler handler = new Handler(Looper.getMainLooper());
                        handler.post(new Runnable()
                        {
                              @Override
                              public void run()
                              {
                                    requestLayout();
                                    invalidate();
                              }
                        });

                  }
                  catch (ParserConfigurationException | IOException | SAXException e)
                  {
                        throw new RuntimeException(e);
                  }

            }
      };

      @Override
      protected void onDraw(@NonNull Canvas canvas)
      {
            super.onDraw(canvas);
            if (itemList != null && itemList.size() > 0)
            {
                  canvas.save();
                  canvas.translate(translateX, translateY);
                  canvas.scale(scale, scale);

                  for (ProvinceItem provinceItem : itemList)
                  {
                        if (provinceItem != select)
                        {
                              provinceItem.drawItem(canvas, paint, false);
                        }
                        else
                        {
                              provinceItem.drawItem(canvas, paint, true);
                        }
                  }

                  if (shouldShowText)
                  {
                        //绘制文本
                        paint.setColor(Color.RED);
                        paint.setStyle(Paint.Style.FILL);
                        paint.setTextSize(40);
                        canvas.drawText(select.getName(), select.getClickPoint().x, select.getClickPoint().y, paint);

                  }
                  canvas.restore();
            }
      }

      @Override
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
      {
            // super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);

            if (totalRect != null)
            {
                  float mapWidth = totalRect.width();
                  scale = width / mapWidth;
            }
            setMeasuredDimension(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
      }

      @Override
      public boolean onTouchEvent(MotionEvent event)
      {
            float x = event.getX();
            float y = event.getY();
            float currentScalecount = 0; //当前缩放系数
            float currentTranslateX = 0;
            float currentTranslateY = 0;


            switch (event.getAction() & MotionEvent.ACTION_MASK)
            {
                  case MotionEvent.ACTION_DOWN:  //单点触控
                        startPoint.set(event.getX(), event.getY());
                        mode = DRAG;
                        actionClick = true;
                        break;
                  case MotionEvent.ACTION_POINTER_DOWN: // 多点触控
                        oriDis = distane(event);
                        if (oriDis > 10)
                        {
                              midPoint = midPoint(event);
                              mode = ZOOM;
                        }
                        actionClick = false;
                        break;
                  case MotionEvent.ACTION_MOVE:
                        if (mode == DRAG)  //单指拖动
                        {
                              if (Math.abs(x - startPoint.x) > 10 || Math.abs(y - startPoint.y) > 10)
                              {
                                    currentTranslateX = translateX + x - startPoint.x;
                                    currentTranslateY = translateY + y - startPoint.y;
                                    translateX = currentTranslateX;
                                    translateY = currentTranslateY;
                                    startPoint.set(x, y);
                                    actionClick = false;
                                    invalidate();
                              }

                        }
                        else if (mode == ZOOM) //双指缩放
                        {
                              float newDist = distane(event);
                              if (Math.abs(newDist - oriDis) > 10)
                              {
                                    float scaleInner = newDist / oriDis;
                                    currentScalecount = scale + scaleInner - 1;
                                    if (currentScalecount < 1)
                                    {
                                          scale = 1;
                                    }
                                    else
                                    {
                                          scale = currentScalecount;
                                    }
                                    oriDis = newDist;
                                    invalidate();
                              }

                        }
                        break;
                  case MotionEvent.ACTION_UP:
                        mode = NONE;
                        if (actionClick)
                        {
                              HandlerTouch(x / scale - translateX, y / scale - translateY);
                        }
                        break;
                  case MotionEvent.ACTION_POINTER_UP:
                        mode = NONE;
                        break;


            }
            return true;
      }

      private void HandlerTouch(float x, float y)
      {
            shouldShowText = false;
            if (itemList == null)
            {
                  return;
            }

            ProvinceItem selectItem = null;
            for (ProvinceItem provinceItem : itemList)
            {
                  if (provinceItem.isTouch(x, y))
                  {
                        selectItem = provinceItem;
                        provinceItem.setClickPoint(new PointF(x, y));
                        shouldShowText = true;
                  }

            }
            if (selectItem != null)
            {
                  select = selectItem;
                  postInvalidate();
            }

            Log.e("TAG", "现在select对象里的name 是 " + select.getName());

      }

      private PointF midPoint(MotionEvent event)
      {
            float x = (event.getX(0) + event.getY(1)) / 2;
            float y = (event.getY(0) + event.getY(1)) / 2;
            return new PointF(x, y);
      }

      private float distane(MotionEvent event)
      {
            float x = event.getX(0) + event.getY(1);
            float y = event.getY(0) + event.getY(1);
            return (float) Math.sqrt(x * x + y * y);
      }
}
